﻿using LayuiMvc.DataEntity.DataEntity;
using LayuiMvc.DataModel.Community;
using LayuiMvc.DataEntity;
using LayuiMvc.DataEntity.DataEnum;
using LayuiMvcUtil.Exception;
using LayuiMvcUtil.Result;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using LayuiMvc.Logic.LogicEnum;
using LayuiMvc.DataEntity.IdentityEntity;
using System.Collections.Generic;

namespace LayuiMvc.Logic.Community
{
    /// <summary>
    /// 帖子管理业务逻辑类
    /// </summary>
    public class PostService
    {
        #region 帖子管理==发表帖子

        /// <summary>
        /// 发表帖子
        /// </summary>
        /// <param name="saveEntity">需要发表的帖子的实体类</param>
        /// <returns></returns>
        public async Task<int> PostAddSaveAsync(PostEntity saveEntity)
        {
            using(EFContext db=new EFContext())
            {
                db.Entry(saveEntity).State = EntityState.Added;
                int affectLineCount = await db.SaveChangesAsync();
                if (affectLineCount==0)
                {
                    throw new CustomException("帖子发表失败");
                }

                return saveEntity.PostId;
            }
        }


        #endregion

        #region 帖子管理==编辑帖子

        /// <summary>
        /// 帖子编辑初始化
        /// </summary>
        /// <param name="postId">帖子Id</param>
        /// <returns></returns>
        public async Task<PostEntity> PostUpdateInitAsync(int postId)
        {
            using (EFContext db=new EFContext())
            {
                PostEntity postEntity = await db.Posts.FirstOrDefaultAsync(m => m.PostId == postId);

                if (postEntity==null)
                {
                    throw new CustomException("帖子不存在");
                }

                return postEntity;
            }
        }
        /// <summary>
        /// 帖子编辑保存
        /// </summary>
        /// <param name="saveEntity">编辑后的帖子实体类</param>
        /// <returns></returns>
        public async Task PostUpdateSaveAsync(PostEntity saveEntity)
        {
            using(EFContext db=new EFContext())
            {
                PostEntity postEntity = await db.Posts.FirstOrDefaultAsync(m => m.PostId == saveEntity.PostId);
                if (postEntity==null)
                {
                    throw new CustomException("帖子不存在");
                }
                postEntity.Content = saveEntity.Content;
                postEntity.HtmlContent = saveEntity.HtmlContent;
                postEntity.Title = saveEntity.Title;

                int affectLineCount = await db.SaveChangesAsync();
                if (affectLineCount==0)
                {
                    throw new CustomException("帖子编辑失败");
                }

            }
        }
        #endregion

        #region 帖子管理==帖子详情

        public async Task<DataResult<PostDetailModel>> PostDetailAsync(int postId,int currentUserId,int pageIndex,int pageSize)
        {
            int skipCount = (pageIndex - 1) * pageSize;
            DataResult<PostDetailModel> rtnResult = new DataResult<PostDetailModel>();

            using (EFContext db = new EFContext())
            {
                PostDetailModel postDetailModel = await (from postEntity in db.Posts
                        .Include(m => m.Replys)
                        .Include("Replys.ReplyUser")
                                                         where !postEntity.IsDelete && postEntity.PostId == postId

                                                         //当前用户信息(子查询不允许用异步)
                                                         let currentUser = (from userEntity in db.Users
                                                                            where userEntity.Id == currentUserId
                                                                            select userEntity).FirstOrDefault()

                                                         //是否已经有回复被采纳
                                                         let isAccept = postEntity.Replys.Any(m => m.IsAccept)

                                                         //该帖子是否被当前用户收藏
                                                         let isCollection = db.PostCollections.Any(m => m.CollectionUserId == currentUserId && m.PostId == postId)


                                                         select new PostDetailModel()
                                                         {
                                                             //帖子信息
                                                             PostId = postEntity.PostId,
                                                             Title = postEntity.Title,
                                                             HtmlContent = postEntity.HtmlContent,
                                                             PublishTime = postEntity.PublishTime,
                                                             ReplyCount = postEntity.Replys.Count,
                                                             ViewCount = postEntity.ViewCount,
                                                             PostType = postEntity.PostType,
                                                             IsTop = postEntity.IsTop,
                                                             IsCream = postEntity.IsCream,
                                                             IsEnd = postEntity.IsEnd,

                                                             //帖子发布者用户信息
                                                             UserId = postEntity.PublishUserId,
                                                             NickName = postEntity.PublishUser.NickName,
                                                             UserIdentity = postEntity.PublishUser.UserIdentity,
                                                             IsApprove = postEntity.PublishUser.IsApprove,
                                                             ApproveMsg = postEntity.PublishUser.ApproveMsg,
                                                             RegisterTime = postEntity.PublishUser.RegisterTime,
                                                             HeadImgUrl = postEntity.PublishUser.HeadImgUrl,

                                                             //当前用户是否为发布者
                                                             IsPublishUser = currentUser.Id == postEntity.PublishUserId,

                                                             //当前登录用户是否为管理员
                                                             IsManageUser = currentUser.UserIdentity == UserIdentityEnum.Admin,

                                                             //当前帖子是否被当前登录用户收藏
                                                             IsCollection = isCollection,

                                                             //是否已经有回复被采纳
                                                             IsAccept = isAccept,

                                                             //帖子回复
                                                             ReplyList = postEntity.Replys.OrderByDescending(m => m.ReplyId).Skip(skipCount).Take(pageSize)
                                                                 .Select(m => new BlogReplyModel()
                                                                 {
                                                                     ReplyId = m.ReplyId,
                                                                     ReplyTime = m.ReplyTime,
                                                                     HtmlContent = m.ReplyContentHtml,
                                                                     IsAccept = m.IsAccept,
                                                                     UserId = m.ReplyUser.Id,
                                                                     NickName = m.ReplyUser.NickName,
                                                                     UserIdentity = m.ReplyUser.UserIdentity,
                                                                     IsApprove = m.ReplyUser.IsApprove,
                                                                     ApproveMsg = m.ReplyUser.ApproveMsg,
                                                                     HeadImgUrl = m.ReplyUser.HeadImgUrl,
                                                                     IsReplyUser = m.ReplyUser.Id == currentUser.Id
                                                                 }).ToList()

                                                         }).FirstOrDefaultAsync();

                rtnResult.data = postDetailModel;
                rtnResult.count = postDetailModel.ReplyCount;
                rtnResult.page = pageIndex;
                rtnResult.limit = pageSize;

            }
            return rtnResult;
        }
        #endregion

        #region 帖子管理==帖子操作

        public async Task PostOperateAsync(int postId,int userId,PostOperateEnum operateEnum)
        {
            using(EFContext db=new EFContext())
            {
                //获取帖子数据
                PostEntity postEntity = await db.Posts.FindAsync(postId);
                if (postEntity==null||postEntity.IsDelete)
                {
                    throw new CustomException("帖子不存在或已被删除");
                }
                //获取当前用户信息
                IdentityUserEntity currentUser = db.Users.Find(userId);
                //是否为管理员
                bool isAdmin = currentUser.UserIdentity == UserIdentityEnum.Admin;
                //是否为帖子发布者
                bool isPublisher = currentUser.Id == postEntity.PublishUserId;

                switch (operateEnum)
                {
                    //只有管理员和帖子发布者才可删除
                    case PostOperateEnum.Detele:
                        if (!isPublisher||!isAdmin)
                        {
                            throw new CustomException("非帖子发布者或管理员不能进行删除操作");
                        }
                        postEntity.IsDelete = true;
                        
                        break;
                    case PostOperateEnum.Top:
                        if (!isAdmin)
                        {
                            throw new CustomException("只有管理员才可进行置顶操作");
                        }
                        postEntity.IsTop = !postEntity.IsTop;
                        break;
                    case PostOperateEnum.Cream:
                        if (!isAdmin)
                        {
                            throw new CustomException("只有管理员才可进行加精操作");
                        }
                        postEntity.IsCream = !postEntity.IsCream;
                        break;
                    case PostOperateEnum.End:
                        if (!isPublisher||!isAdmin)
                        {
                            throw new CustomException("非帖子发布者或管理员不能进行结帖操作");
                        }
                        postEntity.IsEnd = true;
                        break;
                    case PostOperateEnum.AddViewCount:
                        postEntity.ViewCount++;
                        break;
                }
                int affectLineCount = await db.SaveChangesAsync();
                if (affectLineCount==0)
                {
                    throw new CustomException("操作失败");
                }
            }
        }
        #endregion

        #region 帖子管理==收藏管理

        /// <summary>
        /// 添加收藏
        /// </summary>
        /// <param name="saveEntity">收藏实体类</param>
        /// <returns></returns>
        public async Task CollectionAddSaveAsync(PostCollectionEntity saveEntity)
        {
            using(EFContext db=new EFContext())
            {
                PostCollectionEntity collectionEntity = await db.PostCollections.FirstOrDefaultAsync(m => m.PostId == saveEntity.PostId && m.CollectionUserId == saveEntity.CollectionUserId);
                //判断帖子是否已经被收藏了
                if (collectionEntity!=null)
                {
                    throw new CustomException("该帖子已经被收藏了");
                }
                db.PostCollections.Add(saveEntity);
                int affectLineCount = await db.SaveChangesAsync();

                if (affectLineCount==0)
                {
                    throw new CustomException("收藏失败");
                }
            }
        }

        /// <summary>
        /// 取消收藏
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="postId"></param>
        /// <returns></returns>
        public async Task CollectionDeleteSaveAsync(int userId,int postId)
        {
            using(EFContext db=new EFContext())
            {
                PostCollectionEntity collectionEntity = await db.PostCollections.FirstOrDefaultAsync(m => m.CollectionUserId == userId && m.PostId == postId);
                if (collectionEntity==null)
                {
                    throw new CustomException("数据不存在");
                }
                db.PostCollections.Remove(collectionEntity);
                int affectLineCount = await db.SaveChangesAsync();
                if (affectLineCount==0)
                {
                    throw new CustomException("取消收藏失败");
                }
            }
        }
        #endregion

        #region 帖子管理==帖子列表
        /// <summary>
        ///帖子列表
        /// </summary>
        /// <param name="pageIndex">当前页的索引</param>
        /// <param name="pageSize">每页的记录条数</param>
        /// <param name="postType">帖子类型</param>
        /// <param name="postStatus">帖子状态</param>
        /// <param name="postSort">帖子排序</param>
        /// <returns></returns>
        public async Task<DataResult<List<PostListModel>>> PostListAsync(int pageIndex, int pageSize, PostTypeQueryEnum postType, PostStatusQueryEnum postStatus, PostSortQueryEnum postSort)
        {
            DataResult<List<PostListModel>> rtnResult = new DataResult<List<PostListModel>>();

            using(EFContext db=new EFContext())
            {
                var query = db.Posts.Include(m => m.Replys)
                    .Include(m => m.PublishUser)
                    .Where(m => !m.IsDelete);
                
                //帖子分类
                if (postType!=PostTypeQueryEnum.None)
                {
                    PostTypeEnum postTypeEnum = (PostTypeEnum)postType;
                    query = query.Where(m => m.PostType == postTypeEnum);
                }
                //帖子状态
                if (postStatus!=PostStatusQueryEnum.None)
                {
                    switch (postStatus)
                    {
                        case PostStatusQueryEnum.Top:
                            query = query.Where(m => m.IsTop);
                            break;
                        case PostStatusQueryEnum.UnEnd:
                            query = query.Where(m => !m.IsEnd);
                            break;
                        case PostStatusQueryEnum.End:
                            query = query.Where(m => m.IsEnd);
                            break;
                        case PostStatusQueryEnum.Cream:
                            query = query.Where(m => m.IsCream);
                            break;
                    }
                }

                //帖子排序
                switch (postSort)
                {
                    case PostSortQueryEnum.New:
                        query = query.OrderByDescending(m => m.PublishTime);
                        break;
                    case PostSortQueryEnum.Hot:
                        query = query.OrderByDescending(m => m.Replys.Count);
                        break;
                }
                rtnResult.count = await query.CountAsync();

                List<PostListModel> postList = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize)
                    .Select(m => new PostListModel()
                    {
                        PostId = m.PostId,
                        Title = m.Title,
                        PublishTime = m.PublishTime,
                        ReplyCount = m.Replys.Count,
                        ViewCount = m.ViewCount,
                        PostType = m.PostType,
                        IsTop = m.IsTop,
                        IsCream = m.IsCream,
                        IsEnd = m.IsEnd,
                        UserId = m.PublishUser.Id,
                        NickName = m.PublishUser.NickName,
                        UserIdentity = m.PublishUser.UserIdentity,
                        IsApprove = m.PublishUser.IsApprove,
                        ApproveMsg = m.PublishUser.ApproveMsg,
                        HeadImgUrl = m.PublishUser.HeadImgUrl
                    }).ToListAsync();

                rtnResult.data = postList;
                rtnResult.page = pageIndex;
                rtnResult.limit = pageSize;

                return rtnResult;
            }
        }
        #endregion
    }
}
